package com.palmind.parser.mmparser;

import java.io.IOException;
import java.io.InputStream;

import com.palmind.parser.tags.AbstractTag;
import com.palmind.parser.tags.NodeTag;
import com.palmind.parser.tags.factory.TagFactory;
import com.palmind.parser.xmlparser.IXmlParser;
import com.palmind.parser.xmlparser.ParserException;
import com.palmind.parser.xmlparser.XmlParser;
import com.palmind.tree.Tree;
import com.palmind.tree.TreeNode;

public class MMFileParser {
	private Tree tree = null;
	private IXmlParser xmlParser = null;
	private boolean isParsing = false;

	public MMFileParser() {
		xmlParser = new XmlParser();
	}

	public void parser() throws ParserException {
		isParsing = true;
		int eventType = xmlParser.getEventType();
		while (isParsing) {
			// Execute corresponding methods to interpret this kind of tags
			switch (eventType) {
			case IXmlParser.START_DOCUMENT:
				break;
			case IXmlParser.START_TAG:
				parseStartTags2();
				break;
			case IXmlParser.END_TAG:
				parseEndTags();
				break;
			case IXmlParser.TEXT:
				parseText();
				break;
			case IXmlParser.ERROR:
				parseError();
				break;
			case IXmlParser.END_DOCUMENT:
				isParsing = false;
				break;
			}
			// Get the next tag
			try {
				eventType = xmlParser.next();
			} catch (ParserException pe) {
			} catch (IOException ie) {
				eventType = IXmlParser.END_DOCUMENT;
			}
		}
	}

	private void parseStartTags2() {
		// Get tag name
		String name = xmlParser.getName();
		// Get the number of tag's attributions
		int attributeNum = xmlParser.getAttributeNum();
		// Create the bean that corresponds to the tag
		AbstractTag innerTag = TagFactory.createABean(name);
		if (innerTag != null) {
			for (int i = 0; i < attributeNum; i++) {
				innerTag.setAttributeValue(xmlParser.getAttributeName(i),
						xmlParser.getAttributeValue(i));
			}
			if (name.equals(AbstractTag.TAGS[AbstractTag.NODE_TAG])) {
				TreeNode treeNode = new TreeNode();
				treeNode.setBody(innerTag);
				tree.addTreeNode(treeNode);
				treeNode = null;
			} else {
				NodeTag node = getCurrentNode();
				if (node != null) {
					node.addInnerTags(innerTag);
				}
				node = null;
			}
			innerTag = null;
		} else {
			if (name.equals(AbstractTag.TAGS[AbstractTag.MAP_TAG])) {
				if (tree == null)
					tree = new Tree();
				for (int i = 0; i < attributeNum; i++) {
					if (xmlParser.getAttributeName(i).equals("version")) {
						tree.setVersion(xmlParser.getAttributeValue(i));
						break;
					}
				}
			}
		}
	}

	private NodeTag getCurrentNode() {
		TreeNode treeNode = tree.getCurNode();
		if (treeNode != null) {
			NodeTag node = (NodeTag) treeNode.getBody();
			treeNode = null;
			return node;
		}
		return null;
	}

	private void parseEndTags() {
		String name = xmlParser.getName();
		if (name.equals(AbstractTag.TAGS[AbstractTag.NODE_TAG])) {
			if (tree != null)
				tree.goBack();
		}
	}

	private void parseText() {

	}

	private void parseError() {

	}

	public Tree getTree() {
		return tree;
	}

	public void setFileStream(InputStream fileStream, String encodeStr)
			throws ParserException {
		if (xmlParser == null)
			xmlParser = new XmlParser();
		xmlParser.setInput(fileStream, encodeStr);
	}
}
